package com.campus_activity.campus_activity.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.campus_activity.campus_activity.constant.HttpStatus;
import com.campus_activity.campus_activity.domain.dto.LoginDTO;
import com.campus_activity.campus_activity.domain.dto.UserDTO;
import com.campus_activity.campus_activity.domain.po.User;
import com.campus_activity.campus_activity.exception.BusinessException;
import com.campus_activity.campus_activity.mapper.UserMapper;
import com.campus_activity.campus_activity.service.LoginService;
import com.campus_activity.campus_activity.service.VerifyCodeService;

import com.campus_activity.campus_activity.utils.PasswordUtils;
import com.campus_activity.campus_activity.utils.RedisCache;
import com.campus_activity.campus_activity.utils.VerifyUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;


@Service
@RequiredArgsConstructor
public class LoginServiceImpl implements LoginService {


    private final UserMapper userMapper;

    private final RedisCache redisCache;

    private final VerifyCodeService verifyCodeService;

    /**
     * 用户手机验证码登录
     *
     * @param loginDTO
     * @return
     */
    @Override
    public String loginByPhone(LoginDTO loginDTO) {

        //验证手机号是否合法
        boolean ifPhone = VerifyUtils.isPhone(loginDTO.getPhone());
        if(!ifPhone)
            throw new BusinessException(HttpStatus.ERROR, "手机号不合法");

        //获得手机号与验证码
        String phone = loginDTO.getPhone();
        String code = loginDTO.getPassword();

        //从Redis中获取缓存的验证码
        String realCode = redisCache.getCacheObject(phone);

        //判断验证码
        if (!verifyCodeService.confirmMsg(phone, code)) {
            throw new BusinessException(HttpStatus.ERROR, "验证码错误");
        }
        //查找用户
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone, phone);
        User user = userMapper.selectOne(queryWrapper);

        //判断用户是否存在
        if (user == null) {
            throw new BusinessException(HttpStatus.ERROR, "用户不存在");
        }

        //用户登录
        StpUtil.login(user.getId());
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();

        //删除Redis中缓存的验证码
        redisCache.deleteObject(phone);

        //返回token
        return tokenInfo.getTokenValue();
    }

    /**
     * 用户手机密码登录
     *
     * @param loginDTO
     * @return
     */
    @Override
    public String loginByPwd(LoginDTO loginDTO) {

        //获取账号、密码
        String phone = loginDTO.getPhone();
        String password = loginDTO.getPassword();
//        String password = DigestUtils.md5DigestAsHex(loginDto.getPassword().getBytes());

        //查找用户
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone, phone);

        User user = userMapper.selectOne(queryWrapper);

        //判断用户是否存在
        if (user == null) {
            throw new BusinessException(HttpStatus.ERROR, "用户不存在");
        }

        //若密码正确，用户登录
        if (!PasswordUtils.confirmPassword(password,user.getPassword())) {
            throw new BusinessException(HttpStatus.ERROR, "密码错误");
        }

        //登录
        StpUtil.login(user.getId());
        //获取token
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();

        //返回token
        return tokenInfo.getTokenValue();
    }

    /**
     * 用户注册
     * @param userDTO
     * @return
     */
    @Override
    public Boolean register(UserDTO userDTO) {

        //查找用户
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone, userDTO.getPhone());
        User userFind = userMapper.selectOne(queryWrapper);

        //判断是否为空
        if (userFind != null) {
            throw new BusinessException(HttpStatus.ERROR, "该用户已存在");
        }

        //新建用户
        User user = new User();
        BeanUtils.copyProperties(userDTO,user);

        //获取原始密码
        String password = userDTO.getPassword();

        //密码加密
        String pw_hash = PasswordUtils.encryptPassword(password);

        //设置加密后密码
        user.setPassword(pw_hash);

        //插入数据
        userMapper.insert(user);

        return true;
    }
}
